// 引用头文件
#include "py/builtin.h"
#include "py/runtime.h"
#include "py/obj.h"
#include "py/binary.h"
#include <stdlib.h>


extern const mp_obj_type_t mpu6050_hw_type;          // 定义MPU6050数据类型

typedef struct _hw_mpu6050_obj_t {
    mp_obj_base_t base;
    bool status;
    float roll;
    float pitch;
    float yaw;
} hw_mpu6050_obj_t;                                  // 定义MPU6050的结构体

/*--------------------------定义mpu6050模块-----------------------------*/

// 定义全局字典
static const mp_rom_map_elem_t mpu6050_module_globals_table[] = {
    { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_mpu6050) },
    { MP_ROM_QSTR(MP_QSTR_MPU6050), MP_ROM_PTR(&mpu6050_hw_type) }
};

// 将全局字典转换为micropython对象
static MP_DEFINE_CONST_DICT(mpu6050_module_globals, mpu6050_module_globals_table);

// 定义模块原型并注册
const mp_obj_module_t mp_module_mpu6050 = {
    .base = {&mp_type_module},
    .globals = (mp_obj_dict_t *)&mpu6050_module_globals
};

MP_REGISTER_MODULE(MP_QSTR_mpu6050, mp_module_mpu6050);

/*--------------------------定义mpu6050.MPU6050()类-----------------------------*/

mp_obj_t hw_mpu6050_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
    hw_mpu6050_obj_t *self = NULL;
    self = mp_obj_malloc(hw_mpu6050_obj_t, &mpu6050_hw_type);

    return MP_OBJ_FROM_PTR(self);
}

/*-------------------------定义类的方法---------------------------------------*/

static mp_obj_t hw_mpu6050_start(mp_obj_t self_in) {
    hw_mpu6050_obj_t *self = MP_OBJ_TO_PTR(self_in);
    self->status = true;

    return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(hw_mpu6050_start_obj, hw_mpu6050_start);

static mp_obj_t hw_mpu6050_read(mp_obj_t self_in) {
    hw_mpu6050_obj_t *self = MP_OBJ_TO_PTR(self_in);
    mp_obj_t euler[] = {
        mp_obj_new_float(self->roll),
        mp_obj_new_float(self->pitch),
        mp_obj_new_float(self->yaw)
    };

    return mp_obj_new_list(3, euler);
}
static MP_DEFINE_CONST_FUN_OBJ_1(hw_mpu6050_read_obj, hw_mpu6050_read);

static mp_obj_t hw_mpu6050_stop(mp_obj_t self_in) {
    hw_mpu6050_obj_t *self = MP_OBJ_TO_PTR(self_in);
    self->status = false;

    return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(hw_mpu6050_stop_obj, hw_mpu6050_stop);

static const mp_rom_map_elem_t hw_mpu6050_locals_dict_table[] = {
    { MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&hw_mpu6050_start_obj) },
    { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&hw_mpu6050_read_obj) },
    { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&hw_mpu6050_stop_obj) },
};
MP_DEFINE_CONST_DICT(hw_mpu6050_locals_dict, hw_mpu6050_locals_dict_table);

MP_DEFINE_CONST_OBJ_TYPE(
    mpu6050_hw_type,                       // 定义类型名称
    MP_QSTR_MPU6050,                       // 类型的名称字符串
    MP_TYPE_FLAG_NONE,                     // 无特殊标志
    make_new, hw_mpu6050_make_new,         // 对象创建函数, 对应i2c = machine.I2C()
    locals_dict, &hw_mpu6050_locals_dict   // 用来定义类的方法或属性
);
